﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;

using ClientLib;

namespace JigsawAdmin.SubForms.Security
{
    public partial class API : Form
    {
        ClientUtil _cutil;
        TreeNode _selectednode;
        JsvcEnc.EncSoapXml xmlsvc;

        public API(ClientUtil cUtil)
        {
            InitializeComponent();

            try
            {
                _cutil = cUtil;
                xmlsvc = new JsvcEnc.EncSoapXml();
                xmlsvc.Url = _cutil.ServiceURL;

                // set up folder images for treeview
                ImageList apiTreeList = new ImageList();
                apiTreeList.Images.Add(Image.FromFile("../../Images/Folder.png"));
                apiTreeList.Images.Add(Image.FromFile("../../Images/Node.png"));
                apiTreeList.Images.Add(Image.FromFile("../../Images/Rootfolder.png"));

                trvAPI.ImageList = apiTreeList;
                trvAPI.ImageIndex = 0;
                trvAPI.SelectedImageIndex = 1;
            }
            catch (Exception ex)
            {
                ErrorUtil eutil = new ErrorUtil();
                eutil.LogException(_cutil.UserID, "API API", "", ex);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void API_Shown(object sender, EventArgs e)
        {
            try
            {
                PopulateAPITree();
            }
            catch (Exception ex)
            {
                ErrorUtil eutil = new ErrorUtil();
                eutil.LogException(_cutil.UserID, "API API_Shown", "", ex);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void trvAPI_AfterSelect(object sender, TreeViewEventArgs e)
        {
            try
            {
                ClearAPIForm();

                // assign the selected node
                _selectednode = trvAPI.SelectedNode;

                TreeEvents();
            }
            catch (Exception ex)
            {
                ErrorUtil eutil = new ErrorUtil();
                eutil.LogException(_cutil.UserID, "API trvAPI_AfterSelect", "", ex);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        private void TreeEvents()
        {
            switch (_selectednode.Level)
            {
                case 0:
                    // root node level - do nothing
                    //_selectednode.Toggle();
                    break;

                case 1:
                    if (_selectednode.Nodes.Count == 0)
                    {
                        // API level, get Methods
                        PopulateMethods();
                    }
                    break;

                case 2:
                    // Method level, populate method versions grid
                    PopulateMethodVersions();
                    break;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public void PopulateAPITree()
        {
            // populate the top level of the tree
            Dictionary<string, string> paramList = new Dictionary<string, string>();

            string encryptedinput = _cutil.BuildMessageXML("SystemAdmin.GetAllAPIs.Base", paramList, true);
            string results = xmlsvc.Controller(_cutil.EncSymmKey, encryptedinput);

            EncryptUtil eutil = new EncryptUtil();
            _cutil.ParseResponseMessage(eutil.DecryptString2(results, _cutil.SymmKey));

            if (_cutil.ResponseCode == "Success")
            {
                string tmpdata = _cutil.Result;
                tmpdata = tmpdata.Replace("<![CDATA[", "");
                tmpdata = tmpdata.Replace("]]>", "");

                StringReader sr = new StringReader(tmpdata);
                DataTable apilist = new DataTable();
                apilist.ReadXml(sr);

                if (apilist.Rows.Count > 0)
                {
                    trvAPI.BeginUpdate();
                    trvAPI.Nodes.Clear();

                    // populate root node of API tree
                    APITreeNode atnr = new APITreeNode();
                    atnr.Name = "Jigsaw Libraries";
                    atnr.Type = "Root";
                    atnr.APIName = "Jigsaw Libraries";

                    TreeNode tnr = new TreeNode();
                    tnr.Text = "Jigsaw Libraries";
                    tnr.ImageIndex = 2;
                    tnr.SelectedImageIndex = 2;
                    tnr.Tag = atnr;

                    trvAPI.Nodes.Add(tnr);

                    // populate top level of API tree
                    foreach (DataRow dr in apilist.Rows)
                    {
                        APITreeNode atn = new APITreeNode();
                        atn.Name = dr["APIName"].ToString();
                        atn.Type = "API";
                        atn.APIName = dr["APIName"].ToString();

                        TreeNode tn = new TreeNode();
                        tn.Text = dr["APIName"].ToString();
                        tn.ImageIndex = 0;
                        tn.SelectedImageIndex = 0;
                        tn.Tag = atn;

                        tnr.Nodes.Add(tn);
                    }

                    trvAPI.EndUpdate();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public void PopulateMethods()
        {
            // get info from the selected tree node and tag object
            APITreeNode selectedTag = (APITreeNode)_selectednode.Tag;

            Dictionary<string, string> paramList = new Dictionary<string, string>();
            paramList.Add("APIName", selectedTag.APIName);

            string encryptedinput = _cutil.BuildMessageXML("SystemAdmin.GetAPIMethods.Base", paramList, true);
            string results = xmlsvc.Controller(_cutil.EncSymmKey, encryptedinput);

            EncryptUtil eutil = new EncryptUtil();
            _cutil.ParseResponseMessage(eutil.DecryptString2(results, _cutil.SymmKey));

            if (_cutil.ResponseCode == "Success")
            {
                string tmpdata = _cutil.Result;
                tmpdata = tmpdata.Replace("<![CDATA[", "");
                tmpdata = tmpdata.Replace("]]>", "");

                StringReader sr = new StringReader(tmpdata);
                DataTable methlist = new DataTable();
                methlist.ReadXml(sr);

                if (methlist.Rows.Count > 0)
                {
                    trvAPI.BeginUpdate();

                    foreach (DataRow dr in methlist.Rows)
                    {
                        APITreeNode atn = new APITreeNode();
                        atn.Name = dr["MethodName"].ToString();
                        atn.Type = "Method";
                        atn.APIName = selectedTag.Name;
                        atn.MethodName = dr["MethodName"].ToString();
                        atn.GID = dr["GlobalID"].ToString();

                        TreeNode tn = new TreeNode();
                        tn.Text = dr["MethodName"].ToString();
                        tn.ImageIndex = 1;
                        tn.SelectedImageIndex = 1;
                        tn.Tag = atn;

                        _selectednode.Nodes.Add(tn);
                    }

                    trvAPI.EndUpdate();
                    trvAPI.Refresh();
                    trvAPI.SelectedNode.Expand();
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public void PopulateMethodVersions()
        {
            // get info from the selected tree node and tag object
            APITreeNode selectedTag = (APITreeNode)_selectednode.Tag;
            lblSelectedAPI.Text = "Selected Method: " + selectedTag.MethodName;
            Dictionary<string, string> paramList = new Dictionary<string, string>();
            paramList.Add("MethodID", selectedTag.GID);

            string encryptedinput = _cutil.BuildMessageXML("SystemAdmin.GetMethodVersions.Base", paramList, true);
            string results = xmlsvc.Controller(_cutil.EncSymmKey, encryptedinput);

            EncryptUtil eutil = new EncryptUtil();
            _cutil.ParseResponseMessage(eutil.DecryptString2(results, _cutil.SymmKey));

            if (_cutil.ResponseCode == "Success")
            {
                string tmpdata = _cutil.Result;
                tmpdata = tmpdata.Replace("<![CDATA[", "");
                tmpdata = tmpdata.Replace("]]>", "");

                StringReader sr = new StringReader(tmpdata);
                DataTable verlist = new DataTable();
                verlist.ReadXml(sr);

                if (verlist.Rows.Count > 0)
                {
                    dgvMethodVersions.DataSource = verlist;
                    PopulateAPIForm();
                }
                else
                {
                    dgvMethodVersions.DataSource = null;
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        private void ClearAPIForm()
        {
            lblSelectedAPI.Text = "Selected Method:";
            dgvMethodVersions.DataSource = null;
            txtGlobalID.Text = "";
            txtFullMethodName.Text = "";
            txtLibraryName.Text = "";
            cmbActionType.SelectedIndex = -1;
            cmbMethodState.SelectedIndex = -1;

            btnSave.Enabled = false;
            btnDelete.Enabled = false;
            btnRollback.Enabled = false;
        }

        /// <summary>
        /// reloads the API tree
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnRefreshTree_Click(object sender, EventArgs e)
        {
            try
            {
                ClearAPIForm();
                PopulateAPITree();
            }
            catch (Exception ex)
            {
                ErrorUtil eutil = new ErrorUtil();
                eutil.LogException(_cutil.UserID, "API btnRefreshTree_Click", "", ex);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dgvMethodVersions_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            PopulateAPIForm();
        }

        /// <summary>
        /// 
        /// </summary>
        private void PopulateAPIForm()
        {
            txtGlobalID.Text = dgvMethodVersions.SelectedRows[0].Cells["GlobalID"].Value.ToString();
            txtLibraryName.Text = dgvMethodVersions.SelectedRows[0].Cells["APIName"].Value.ToString();
            txtFullMethodName.Text = dgvMethodVersions.SelectedRows[0].Cells["MethodName"].Value.ToString();
            cmbActionType.SelectedItem = dgvMethodVersions.SelectedRows[0].Cells["ActionType"].Value.ToString();
            cmbMethodState.SelectedItem = dgvMethodVersions.SelectedRows[0].Cells["MethodState"].Value.ToString();

            btnSave.Enabled = true;
            btnDelete.Enabled = true;
            string rowstate = dgvMethodVersions.SelectedRows[0].Cells["RowState"].Value.ToString();
            if (rowstate != "Active")
            {
                btnRollback.Enabled = true;
                btnDelete.Enabled = false;
            }
            else
            {
                btnRollback.Enabled = false;
                btnDelete.Enabled = true;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnNew_Click(object sender, EventArgs e)
        {
            ClearAPIForm();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnSave_Click(object sender, EventArgs e)
        {
            if (ValidateData())
            {
                string action = "";
                Dictionary<string, string> paramList = new Dictionary<string, string>();
                paramList.Add("ActionType", cmbActionType.SelectedItem.ToString());
                paramList.Add("APIName", txtLibraryName.Text);
                paramList.Add("MethodName", txtFullMethodName.Text);
                paramList.Add("MethodState", cmbMethodState.SelectedItem.ToString());

                string encryptedinput = "";
                if (txtGlobalID.Text.Length > 0)
                {
                    // update existing record
                    paramList.Add("GlobalID", txtGlobalID.Text);
                    encryptedinput = _cutil.BuildMessageXML("SystemAdmin.SaveMethod.Base", paramList, true);
                }
                else
                {
                    // insert new record
                    paramList.Add("GlobalID", _cutil.GetNewID());
                    encryptedinput = _cutil.BuildMessageXML("SystemAdmin.NewMethod.Base", paramList, true);
                    action = "New";
                }

                string results = xmlsvc.Controller(_cutil.EncSymmKey, encryptedinput);

                EncryptUtil eutil = new EncryptUtil();
                _cutil.ParseResponseMessage(eutil.DecryptString2(results, _cutil.SymmKey));

                if (_cutil.ResponseCode == "Success")
                {
                    ClearAPIForm();
                    if (action == "New")
                    {
                        PopulateAPITree();
                    }
                    else
                    {
                        TreeEvents();
                    }
                }
                else
                {
                    MessageBox.Show(_cutil.Result);
                }
            }
            else
            {
                MessageBox.Show("You must provide a value for all required fields.", "Data Validation");
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (ValidateData())
            {
                Dictionary<string, string> paramList = new Dictionary<string, string>();
                paramList.Add("GlobalID", txtGlobalID.Text);
                paramList.Add("ActionType", cmbActionType.SelectedItem.ToString());
                paramList.Add("APIName", txtLibraryName.Text);
                paramList.Add("MethodName", txtFullMethodName.Text);
                paramList.Add("MethodState", cmbMethodState.SelectedItem.ToString());

                // update existing record
                string encryptedinput = _cutil.BuildMessageXML("SystemAdmin.DeleteMethod.Base", paramList, true);
                string results = xmlsvc.Controller(_cutil.EncSymmKey, encryptedinput);

                EncryptUtil eutil = new EncryptUtil();
                _cutil.ParseResponseMessage(eutil.DecryptString2(results, _cutil.SymmKey));

                if (_cutil.ResponseCode == "Success")
                {
                    ClearAPIForm();
                    PopulateAPITree();
                }
                else
                {
                    MessageBox.Show(_cutil.Result);
                }
            }
            else
            {
                MessageBox.Show("You must provide a value for all required fields.", "Data Validation");
            }
        }

        /// <summary>
        /// Saves selected archived record as new Active record
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnRollback_Click(object sender, EventArgs e)
        {
            Dictionary<string, string> paramList = new Dictionary<string, string>();
            paramList.Add("GlobalID", txtGlobalID.Text);
            paramList.Add("ActionType", cmbActionType.SelectedItem.ToString());
            paramList.Add("APIName", txtLibraryName.Text);
            paramList.Add("MethodName", txtFullMethodName.Text);
            paramList.Add("MethodState", cmbMethodState.SelectedItem.ToString());
            
            // update existing record
            string encryptedinput = _cutil.BuildMessageXML("SystemAdmin.SaveMethod.Base", paramList, true);
            string results = xmlsvc.Controller(_cutil.EncSymmKey, encryptedinput);

            EncryptUtil eutil = new EncryptUtil();
            _cutil.ParseResponseMessage(eutil.DecryptString2(results, _cutil.SymmKey));

            if (_cutil.ResponseCode == "Success")
            {
                ClearAPIForm();
            }
            else
            {
                MessageBox.Show(_cutil.Result);
            }
        }

        /// <summary>
        /// used after New button clears form;
        /// last data entry control validates required fields,
        /// enables Save button if validated.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmbMethodState_SelectedIndexChanged(object sender, EventArgs e)
        {
            bool valid = ValidateData();
            if (valid)
            {
                btnSave.Enabled = true;
            }
            else
            {
                btnSave.Enabled = false;
            }
        }

        /// <summary>
        /// will not enable the save button unless all required fields have values
        /// </summary>
        private bool ValidateData()
        {
            bool isValid = true;

            if (txtFullMethodName.Text == "") isValid = false;
            if (txtLibraryName.Text == "") isValid = false;
            if (cmbActionType.SelectedIndex == -1) isValid = false;
            if (cmbMethodState.SelectedIndex == -1) isValid = false;

            return isValid;
        }

    }


    /// <summary>
    /// Data class to hold tree node values
    /// </summary>
    public class APITreeNode
    {
        private string _name = "";
        private string _type = "";
        private string _gid = "";
        private string _apiname = "";
        private string _methodname = "";

        public APITreeNode()
        {

        }

        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        public string Type
        {
            get { return _type; }
            set { _type = value; }
        }

        public string GID
        {
            get { return _gid; }
            set { _gid = value; }
        }

        public string APIName
        {
            get { return _apiname; }
            set { _apiname = value; }
        }

        public string MethodName
        {
            get { return _methodname; }
            set { _methodname = value; }
        }
    }
}
